﻿using System.Collections.Generic;
using ProgrammingPatterns.DesignPatterns.Creational.Prototype;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ProgrammingPatternsTest.DesignPatterns.Creational.Prototype
{
    /// <summary>
    ///This is a test class for CountryClientTest and is intended
    ///to contain all CountryClientTest Unit Tests
    ///</summary>
    [TestClass]
    public class CountryClientTest
    {
        /// <summary>
        /// Gets or sets the prototype manager.
        /// </summary>
        /// <value>The prototype manager.</value>
        public CountryManager PrototypeManager { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="CountryClientTest"/> class.
        /// </summary>
        public CountryClientTest()
        {
            // instantiate the prototype managet object
            PrototypeManager =
                new CountryManager
                    {
                        Countries =
                            new Dictionary<string, Country>
                                {
                                    {"Germany", new Country("Germany", "Berlin", "German")},
                                    {"Italy", new Country("Italy", "Rome", "Italian")},
                                    {"Australia", new Country("Australia", "Canberra", "English")}
                                }
                    };
        }

        /// <summary>
        ///A test for Report: shallow clone test
        ///</summary>
        [TestMethod]
        public void ReportTest_Shallow()
        {
            var target = new CountryClient();

            // Make a shallow copy of Australia's data
            var clone = PrototypeManager.Countries["Australia"].Clone();
            Assert.AreNotEqual(clone, PrototypeManager.Countries["Australia"]);

            const string expected = "Prototype:Australia-Canberra-English :: Clone:Australia-Canberra-English";
            Assert.AreEqual(target.Report(clone, PrototypeManager.Countries["Australia"]), expected);
        }

        /// <summary>
        ///A test for Report: altered shallow clone test
        ///</summary>
        [TestMethod]
        public void ReportTest_AlteredShallow()
        {
            var target = new CountryClient();

            // Make a shallow copy of Australia's data and alter its capital
            var clone = PrototypeManager.Countries["Australia"].Clone();
            clone.Capital = "Sydney";
            Assert.AreNotEqual(clone, PrototypeManager.Countries["Australia"]);
            Assert.AreNotEqual(clone.Capital, PrototypeManager.Countries["Australia"].Capital);

            const string expected = "Prototype:Australia-Sydney-English :: Clone:Australia-Canberra-English";
            Assert.AreEqual(target.Report(clone, PrototypeManager.Countries["Australia"]), expected);
        }

        /// <summary>
        ///A test for Report: altered deep data shallow clone test
        ///</summary>
        [TestMethod]
        public void ReportTest_AlteredShallowDeepData()
        {
            var target = new CountryClient();

            // Make a shallow copy of Australia's data and alter its language (deep data)
            var clone = PrototypeManager.Countries["Australia"].Clone();
            clone.Language.Data = "Chinese";
            Assert.AreNotEqual(clone, PrototypeManager.Countries["Australia"]);

            const string expected = "Prototype:Australia-Canberra-Chinese :: Clone:Australia-Canberra-Chinese";
            Assert.AreEqual(target.Report(clone, PrototypeManager.Countries["Australia"]), expected);
        }

        /// <summary>
        ///A test for Report: deep clone test
        ///</summary>
        [TestMethod]
        public void ReportTest_Deep()
        {
            var target = new CountryClient();

            // Make a deep copy of Germany's data
            var clone = PrototypeManager.Countries["Germany"].DeepCopy();
            Assert.AreNotEqual(clone, PrototypeManager.Countries["Germany"]);

            const string expected = "Prototype:Germany-Berlin-German :: Clone:Germany-Berlin-German";
            Assert.AreEqual(target.Report(clone, PrototypeManager.Countries["Germany"]), expected);
        }

        /// <summary>
        ///A test for Report: altered deep clone test
        ///</summary>
        [TestMethod]
        public void ReportTest_AlteredDeep()
        {
            var target = new CountryClient();

            // Make a deep copy of Germany's data and alter its capital
            var clone = PrototypeManager.Countries["Germany"].DeepCopy();
            clone.Capital = "Bonn";
            Assert.AreNotEqual(clone, PrototypeManager.Countries["Germany"]);
            Assert.AreNotEqual(clone.Capital, PrototypeManager.Countries["Germany"].Capital);

            const string expected = "Prototype:Germany-Bonn-German :: Clone:Germany-Berlin-German";
            Assert.AreEqual(target.Report(clone, PrototypeManager.Countries["Germany"]), expected);
        }

        /// <summary>
        ///A test for Report: altered deep data deep clone test
        ///</summary>
        [TestMethod]
        public void ReportTest_AlteredDeepDeepData()
        {
            var target = new CountryClient();

            // Make a deep copy of Germany's data and alter its language (deep data)
            var clone = PrototypeManager.Countries["Germany"].DeepCopy();
            clone.Language.Data = "English";
            Assert.AreNotEqual(clone, PrototypeManager.Countries["Germany"]);

            const string expected = "Prototype:Germany-Berlin-English :: Clone:Germany-Berlin-German";
            Assert.AreEqual(target.Report(clone, PrototypeManager.Countries["Germany"]), expected);
        }
    }
}